package top.gytf.unifiedcall.producer.response;

import cn.hutool.cache.Cache;
import cn.hutool.cache.CacheUtil;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import top.gytf.distools.lifecycle.AbstractLifecycle;
import top.gytf.distools.lifecycle.Manager;
import top.gytf.unifiedcall.common.api.ApiDefinition;
import top.gytf.unifiedcall.model.detail.UnifiedCallPackageDetail;

import java.util.Comparator;
import java.util.List;
import java.util.Objects;

/**
 * 通用的响应处理器管理器
 */
@Getter
@Slf4j
@RequiredArgsConstructor
public class ResponseHandlerManagerImpl extends AbstractLifecycle implements ResponseHandlerManager, Manager {
    private final List<ResponseHandler> responseHandlers;
    private final Cache<ApiDefinition, ResponseHandler[]> supportedHandlersCache = CacheUtil.newLRUCache(256);

    /**
     * @see UnifiedCallPackageDetail#getName()
     */
    private final String enabledPackage;

    @Override
    protected void doInitialize() {
        responseHandlers.sort(Comparator.comparingInt(ResponseHandler::order));
        postProcessResponseHandlers(responseHandlers);
    }

    /**
     * 后置处理响应处理器
     *
     * @param handlers 即将使用的响应处理器
     */
    protected void postProcessResponseHandlers(@SuppressWarnings("unused") List<ResponseHandler> handlers) {
        // do noting
    }

    @Override
    public boolean isSupported(ApiDefinition apiDefinition) {
        assertReady();

        if (!Objects.equals(apiDefinition.getPackageDetail().getName(), enabledPackage)) {
            // 仅支持可用的客户端
            return false;
        }

        return selectSupportedHandlers(apiDefinition).length > 0;
    }

    @Override
    public Object handle(ResponseHandlerContext context) {
        assertReady();

        if (!isSupported(context.getApiDefinition())) {
            // 再次检查是否支持
            return context.getInitialResponse();
        }

        ResponseHandler[] selectedHandlers = selectSupportedHandlers(context.getApiDefinition());
        for (ResponseHandler handler : selectedHandlers) {
            if (context.isCompleted()) {
                break;
            }
            handler.handle(context);
        }

        return context.getResult();
    }

    /**
     * 选择支持该响应的响应处理器列表
     */
    protected ResponseHandler[] selectSupportedHandlers(ApiDefinition basicInfo) {
        return supportedHandlersCache.get(basicInfo, () -> responseHandlers.stream()
                .filter(handler -> handler.isSupported(basicInfo))
                .toArray(ResponseHandler[]::new));
    }
}
